import torch, torchvision
import numpy as np
from torchvision import transforms
import torchvision.datasets as datasets
import torch.nn as nn
import time
class AverageMeter(object):
    """Computes and stores the average and current value"""

    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=1):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count




def accuracy(output, target, topk=(1,)):
    """Computes the precision@k for the specified values of k"""
    maxk = max(topk)
    batch_size = target.size(0)

    _, pred = output.topk(maxk, 1, True, True)
    pred = pred.t()
    correct = pred.eq(target.view(1, -1).expand_as(pred))

    res = []
    for k in topk:
        correct_k = correct[:k].contiguous().view(-1).float().sum(0)
        res.append(correct_k.mul_(100.0 / batch_size))
    return res

def validate(val_loader, model, criterion):
    with torch.no_grad():
        batch_time = AverageMeter()
        losses = AverageMeter()
        top1 = AverageMeter()
        top5 = AverageMeter()

        # switch to evaluate mode
        model.eval()

        end = time.time()
        for i, (input, target) in enumerate(val_loader):
            
            #exit(1)
            target = target.cuda()
            input = input.cuda()
            
            # compute output
            output = model(input)
            loss = criterion(output, target)

            # measure accuracy and record loss
            prec1, prec5 = accuracy(output.data, target.data, topk=(1, 5))
            losses.update(loss.data.item(), input.size(0))
            top1.update(prec1.item(), input.size(0))
            top5.update(prec5.item(), input.size(0))

            # measure elapsed time
            batch_time.update(time.time() - end)
            end = time.time()

            if i % 10 == 0:
                print('Test: [{0}/{1}]\t'
                      'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                      'Loss {loss.val:.4f} ({loss.avg:.4f})\t'
                      'Acc@1 {top1.val:.3f} ({top1.avg:.3f})\t'
                      'Acc@5 {top5.val:.3f} ({top5.avg:.3f})'.format(
                       i, len(val_loader), batch_time=batch_time, loss=losses,
                       top1=top1, top5=top5))

        print(' * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}'
              .format(top1=top1, top5=top5))

        return top1.avg, top5.avg


model = torchvision.models.resnext101_64x4d().cuda()

model.load_state_dict(torch.load("/data1/home/mindspore/yuanyibo/resnext152_vd_64x4d/resnext101_64x4d-173b62eb.pth"))

tf = transforms.Compose([
            transforms.Resize((256, 256)),
            transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize(
              mean=[0.485, 0.456, 0.406],
              std=[0.229, 0.224, 0.225])
            ])
import os
valdir = os.path.join("/data2/dataset/ImageNet2012", 'val')


dataset = datasets.ImageFolder(valdir, tf)

#for input, target in dataset:
#    input = np.array(input)
#    print(input.shape)
#    print(input)
#    print(input.sum())
#    print(input.mean())
#exit(1)

val_loader = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=False, num_workers=8, pin_memory=True)

criterion = nn.CrossEntropyLoss().cuda()

validate(val_loader, model, criterion)

print("*"*30)
#img = np.zeros((224,224,3), dtype=np.uint8)
img = np.fromfile("/data1/home/mindspore/yuanyibo/resnext152_vd_64x4d/data.npy", dtype=np.float32);
img = img.reshape((3, 224, 224))
#print(img)
img_t = torch.Tensor(img)
#pil_image = transforms.ToPILImage()(img)
#img_t = tf(pil_image)

batch_t = torch.unsqueeze(img_t, 0).cuda()

print(batch_t.shape)
#print(model)
model = model.cuda()
model.eval()


out = model(batch_t)
#print(out)
print(out.shape)